<template>
  <div class="dcc-detail-wrap">
    <div v-for="(row, rowIndex) in detailLayout" :key="rowIndex" :class="detailRowClass">
      <div
        v-for="(item, colIndex) in row"
        :key="colIndex"
        class="dcc-detail-item"
        :style="{
          gridColumn: `span ${item.colSpan || 1}`,
        }"
      >
        <!-- label -->
        <slot :name="item.labelSolt" :value="item.label" :item="item" :data="dataSource">
          <span
            v-if="item.label"
            class="dcc-detail-item-label ellipsis"
            :style="labelStyle(item)"
            >{{ item.label }}</span
          >
        </slot>
        <!-- value -->
        <slot :name="item.valueSolt" :value="dataSource[item.prop]" :item="item" :data="dataSource">
          <span class="dcc-detail-item-value ellipsis" :style="valueStyle(item)">
            {{item.formatter ? item.formatter(dataSource[item.prop]) : dataSource[item.prop]}}</span>
        </slot>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  // 申请信息【详情展示组件】TODO
  import { defineProps, computed } from 'vue';

  interface DetailItem {
    label: string;
    prop: string;
    align?: 'left' | 'center' | 'right' | undefined;
    labelAlign?: 'left' | 'center' | 'right' | undefined;
    valueAlign?: 'left' | 'center' | 'right' | undefined;
    labelSolt?: string | undefined;
    valueSolt?: string | undefined;
    formatter?: Function | null; // value格式化方法
    colSpan?: number;
  }

  const props = defineProps({
    // 布局
    layout: {
      type: Array<Array<DetailItem>>,
      default: [],
    },
    // 数据源
    dataSource: {
      type: Object,
      default: () => {
        return {};
      },
    },
    // label width
    labelWidth: {
      type: String,
      default: '100px',
    },
    // 是否展示边框
    border: {
      type: Boolean,
      default: false,
    },
  });

  // label style
  const labelStyle = computed(() => {
    return (item: DetailItem) => {
      return {
        textAlign: item.labelAlign,
        justifyContent: getLabelJustifyContent(item),
        width: props.labelWidth,
      };
    };
  });

  // value style
  const valueStyle = computed(() => {
    return (item: DetailItem) => {
      return {
        textAlign: item.valueAlign,
      };
    };
  });

  // datail row class
  const detailRowClass = computed(() => {
    if (props?.border) return ['dcc-detail-row', 'dcc-detail-row-border'];
    return ['dcc-detail-row'];
  });

  // detail layout
  const detailLayout = computed(() => {
    // 若有传入layout 则采用传入配置
    if (Array.isArray(props.layout) && props.layout.length) return props.layout;
    // 无传入layout 配置 则生成默认layout
    return getDefaultLayout();
  });

  // label style justify-content
  const getLabelJustifyContent = (item: DetailItem) => {
    if ('left' === item.labelAlign) {
      return 'flex-start';
    } else if ('right' === item.labelAlign) {
      return 'flex-end';
    } else {
      return 'center';
    }
  };

  const getDefaultLayout = () => {
    if (!props?.dataSource) return [];
    const layout: Array<Array<DetailItem>> = [];
    // 根据 dataSource 生成默认layout 【每个prop单独一行排列】
    Object.keys(props.dataSource).forEach((key) => {
      layout.push([
        {
          label: key,
          prop: key,
          align: 'left',
          labelAlign: 'right',
          valueAlign: 'left',
        },
      ]);
    });
    return layout;
  };
</script>

<style scoped lang="less">
  .dcc-detail-wrap {
    display: flex;
    flex-direction: column;

    .dcc-detail-row {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));

      .dcc-detail-item {
        display: flex;
        align-items: center;

        .dcc-detail-item-label {
          display: flex;
          align-items: center;
          justify-content: flex-end;
          max-width: 99%;
          height: 100%;
          padding: 0 5px;
          font-weight: bold;
        }

        .dcc-detail-item-value {
          flex: 1;
          padding: 5px;
        }
      }
    }

    .dcc-detail-row-border {
      border-top: 1px solid #dcdbdb;
      border-left: 1px solid #dcdbdb;

      &:last-child {
        border-bottom: 1px solid #dcdbdb;
      }

      .dcc-detail-item {
        border-right: 1px solid #dcdbdb;

        .dcc-detail-item-label {
          border-right: 1px solid #dcdbdb;
          background-color: rgb(5 5 5 / 6%);
        }
      }
    }

    .ellipsis {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
</style>
